﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;

namespace Project
{

    class Teleporter : GameEntity, Renderable
    {
        private Model model;
        private PointLight light;

        private long creationTime; // time of creation
        private static long TIMEOUT = 3000; // timeout after 3 seconds
        public bool usable { get; protected set; }

        public void kill()
        {
            health = -1;
        }

        public void getTeleporterProperties(out Vector3 pos, out Vector3 vel, out Quaternion orient)
        {
            pos = position;
            vel = velocity;
            orient = targetOrientation;
        }

        public Teleporter(Vector3 position, Quaternion orientation, long time)
            : base(position, orientation, 10)
        {
            // don't smooth out rotation
            slerpConstant = 1.00f;

            // bounce everywhere!
            elasticity = 1.0f;

            // gravity = new Vector3(0, 0, 0);
            // ignore friction and drag
            frictionConstant = 0;
            dragConstant = 0;

            // set initial velocity
            velocity = Vector3.Transform(Vector3.Backward, orientation) * 30.0f;

            creationTime = time;

            usable = true;
            
            collisionObject = new CollisionObject(
                new AABB(new Vector3(-0.2f, -0.2f, -0.2f), new Vector3(0.2f, 0.2f, 0.2f), position),
                delegate(CollisionData data) {
                }, this
            );

            // light = new PointLight(position, new Color(0, 0, 0.2f));
        }

        public override void init(GameState gs)
        {
            base.init(gs);
            model = gs.loadAsset<Model>("models\\teleporter");
            gs.getScene().pointLights.Add(light);
            gs.getScene().renderables.Add(this);
        }

        public override void destroy(GameState gs)
        {
            base.destroy(gs);
            gs.getScene().pointLights.Remove(light);
            gs.getScene().renderables.Remove(this);
        }

        public void render(GameTime gt, Camera camera)
        {
            Matrix worldMatrix = Matrix.CreateFromQuaternion(orientation) * Matrix.CreateTranslation(-position);

            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.DiffuseColor = new Vector3(1, 0, 0); // red
                    effect.PreferPerPixelLighting = true;
                    effect.World = worldMatrix;// * transforms[mesh.ParentBone.Index];
                    effect.View = camera.view;
                    effect.Projection = camera.projection;
                }
                mesh.Draw();
            }
        }

        public override bool update(GameTime gt, GameState gs)
        {
            // destroy the entity when it dies or times out
            if (health <= 0 || gt.ElapsedGameTime.Milliseconds > TIMEOUT)
            {
                usable = false;
                return false;
            }

            Vector3 forward = -velocity;
            forward.Z *= -1;
            forward.Normalize();
            Vector3 up = Vector3.Cross(Vector3.Cross(forward, Vector3.Up), forward);
            up.Normalize();
            targetOrientation = Quaternion.CreateFromRotationMatrix(Matrix.CreateLookAt(Vector3.Zero, forward, up));

            light.position = -position;

            return base.update(gt, gs);
        }
    }
}
